package com.huluobo.lib_base

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File

/**
 *  Created by LC on 2025/7/23.
 */
object DownloadUtils {
    fun download(url: String, file: File): Flow<UIState> {
        return flow {
            //通过url和OKHttp的Request构建一个网络请求
            val request = Request.Builder().url(url).get().build()

            //执行上面的网络请求,产生一个返回(response)
            val response = OkHttpClient.Builder().build().newCall(request).execute()

            //如果请求成功
            if (response.isSuccessful) {
                //一个请求都包含header和body
                //要做的事儿是将body中的数据流保存到文件中(file)
                response.body.let { body ->
                    //让文件形成一个输入流,来写入文件
                    file.outputStream().let { os ->
                        //从body中取出字节流,准备写入到file中
                        val bs = body?.byteStream()
                        //字节下标
                        var len = 0
                        //声明字节数组,默认DEFAULT_BUFFER_SIZE 默认缓冲区大小
                        val byteArray = ByteArray(DEFAULT_BUFFER_SIZE)
                        //1.读取body中的字节流,形成一个字节数组
                        //2.一边读取一边给下标赋值
                        //3.将读取到的字节数组和下标,给文件写入内容
                        // 当读取完毕的时候(下标等于-1越界的时候)结束循环4
                        //also 并且的意思
                        while (
                            bs?.read(byteArray).also {
                                len = it!!
                            } != -1
                        ) {
                            os.write(byteArray, 0, len)
                        }
                        //写入完毕,不在进入循环的时候,刷新输出流,保证缓冲区中所有的数据都写入到目标文件中
                        os.flush()
                        //关闭流,不关闭会造成内存泄漏
                        os.close()
                        //发送成功的状态
                        emit(UIState.OnSuccess("下载成功", StateType.DOWNLOAD))
                    }
                }

            } else {
                //发送失败的状态
                emit(UIState.OnFailed("下载失败"))
            }

        }
    }
}